import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:znmm/UI/LoginPages/mag/user_info_manage.dart';
import 'package:logger/logger.dart';
import '../UI/utils/logger_service.dart';
import '../UI/utils/my_global.dart';
import 'api_url.dart';
import 'http_interceptor.dart';

/// 请求方法
enum DioMethod {
  get,
  post,
  put,
  delete,
  patch,
  head,
}

class DioHttps {
  /// 单例模式
  static DioHttps? _instance;
  factory DioHttps() => _instance ?? DioHttps._internal();
  static DioHttps? get instance => _instance ?? DioHttps._internal();

  /// 连接超时时间
  static const int connectTimeout = 60 * 1000;

  /// 响应超时时间
  static const int receiveTimeout = 60 * 1000;

  /// Dio实例（用于不同baseUrl）
  static Dio _dioForBaseUrl0 = Dio(); //服务器0 默认有base
  static Dio _dioForBaseUrl1 = Dio(); //服务器1

  /// 初始化
  DioHttps._internal() {
    _instance = this;

    // 初始化具有不同baseUrl的dio实例
    //默认没有 baseUrl 外面自己拼接
    BaseOptions optionsForBaseUrl0 = BaseOptions(
      baseUrl: APIUrl.strBaseUrl,
      connectTimeout: const Duration(milliseconds: connectTimeout),
      receiveTimeout: const Duration(milliseconds: receiveTimeout),
      contentType: Headers.jsonContentType,
    );
    _dioForBaseUrl0 = Dio(optionsForBaseUrl0);
    _dioForBaseUrl0.interceptors.add(HttpInterceptor());

    BaseOptions optionsForBaseUrl1 = BaseOptions(
      //baseUrl: APIUrl.strBaseUrl,
      connectTimeout: const Duration(milliseconds: connectTimeout),
      receiveTimeout: const Duration(milliseconds: receiveTimeout),
      contentType: Headers.jsonContentType,
    );
    _dioForBaseUrl1 = Dio(optionsForBaseUrl1);
    _dioForBaseUrl1.interceptors.add(HttpInterceptor());
    _dioForBaseUrl1.interceptors
        .add(LogInterceptor(responseHeader: false, responseBody: true));

    // (_dioForBaseUrl1.httpClientAdapter as DefaultHttpClientAdapter)
    //     .onHttpClientCreate = (client) {
    //   // 允许所有证书，仅用于开发阶段，生产中应慎用
    //   client.badCertificateCallback =
    //       (X509Certificate cert, String host, int port) => true;
    //   return client;
    // };

    // 配置 IOHttpClientAdapter
    // final IOHttpClientAdapter adapter = IOHttpClientAdapter()
    //   ..createHttpClient = () {
    //     HttpClient client = HttpClient();
    //     // 忽略证书验证，仅限开发阶段
    //     client.badCertificateCallback =
    //         (X509Certificate cert, String host, int port) => true;
    //     return client;
    //   };

    // _dioForBaseUrl1.httpClientAdapter = adapter;
  }

  /// 请求类
  Future<T> request<T>(
    String pathUrl, {
    DioMethod method = DioMethod.get,
    Map<String, dynamic>? params,
    data,
    CancelToken? cancelToken,
    Options? options1,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
    bool bIsShowLoading = true,
    bool bIsShowRequest = false,
    bool bIsShowResponse = false,
    bool bIsNedToken = true,
    void Function()? callbackOnFail,
  }) async {
    Dio dio;

    //不同baseUrl的dio实例
    if (pathUrl.contains("https:") || pathUrl.contains("http:")) {
      //print("The URL contains 'https:'.");
      dio = _dioForBaseUrl1;
    } else {
      dio = _dioForBaseUrl0;
    }

    const methodValues = {
      DioMethod.get: 'get',
      DioMethod.post: 'post',
      DioMethod.put: 'put',
      DioMethod.delete: 'delete',
      DioMethod.patch: 'patch',
      DioMethod.head: 'head'
    };
    Options options = Options(method: methodValues[method]);

    // 头部添加token
    // options.headers = {
    //   'api-request-source': "soft",
    //   'device': 'mobile',
    //   'token': 'zh-cn',
    // };

    //合并head
    if (options1 != null) {
      Map<String, dynamic> mergedHeaders = {
        ...options.headers ?? {},
        ...options1.headers ?? {}
      };
      options = options.copyWith(headers: mergedHeaders);
    }

    //需要校验
    String username = UserInfoMag().username;
    String password = UserInfoMag().password;
    if (username.isNotEmpty && password.isNotEmpty) {
      Map<String, dynamic>? headers = options.headers ?? {};
      String basicAuth =
          'Basic ${base64Encode(utf8.encode('$username:$password'))}';
      headers['Authorization'] = basicAuth;
      options.headers = headers;
    }

    if (bIsNedToken) {
      // 需要token
      String strToken = ""; //UserInfoManage().getUserInfo().token;
      String strUsername = ""; //UserInfoManage().getUserInfo().username;

      // if (pathUrl.contains("enterprise-mailservice.pintreel.com")) {
      //   ///获取当前时间戳一小时内
      //   DateTime now = DateTime.now();
      //   DateTime roundedTime =
      //       DateTime(now.year, now.month, now.day, now.hour, 0, 0);
      //   int timestampInSeconds = roundedTime.millisecondsSinceEpoch ~/ 1000;

      //   //加密秘钥
      //   const emailwdwd = 'a949ec81d6ebefe84d95dd4a49a570b9';

      //   //加密字符串拼接
      //   var verifyStr = 'un=$strUsername&ts=$timestampInSeconds&key=$emailwdwd';

      //   ///md5加密
      //   strToken = generateMD5(verifyStr);
      // }

      // 初始化并合并 token 和 username 到 headers
      options = options.copyWith(headers: {
        ...?options.headers,
        if (strToken.isNotEmpty) 'token': strToken,
        if (strUsername.isNotEmpty) 'username': strUsername,
        // 'lang': LocaleOptions.getDefault() == const Locale('en', 'US')
        //     ? 'en'
        //     : 'zh-cn',
      });

      // 数据深挖需要另外的请求头
      // if (pathUrl.contains(APIUrl.smsBaseUrl)) {
      //   // 初始化并合并 token 和 username 到 headers
      //   options = options.copyWith(headers: {
      //     ...?options.headers,
      //     if (strToken.isNotEmpty) 'accesstoken': strToken,
      //     if (strUsername.isNotEmpty) 'accessuser': strUsername,
      //   });
      // }
    }

    // if (bIsNedToken) {
    //   // 确保 options.headers 已初始化
    //   options.headers ??= {};
    //   //需要token
    //   String strToken = UserInfoManage().getUserInfo().token;
    //   if (strToken.isNotEmpty) {
    //     options.headers!['token'] = strToken;
    //   }

    //   //需要用户名
    //   String strUsername = UserInfoManage().getUserInfo().username;

    //   if (strUsername.isNotEmpty) {
    //     options.headers!['username'] = strUsername;
    //   }
    // }

    if (bIsShowLoading) {
      MyGlobal.showLoading();
    }

    String queryParametersString = prettyJson(params ?? {});
    String dataString = "";

    if (data is Map<String, dynamic>) {
      dataString = prettyJson(data); //?? {}
    }

    if (bIsShowRequest) {
      logger.d("********** Request **********\n"
          "time: ${DateTime.now()}\n"
          "method: ${options.method}\n"
          "url: ${dio.options.baseUrl}$pathUrl\n"
          "header: ${options.headers}\n"
          "param: $queryParametersString\n"
          "data: $dataString\n");
    }

    Response? response;
    try {
      response = await dio.request(pathUrl,
          data: data,
          queryParameters: params,
          cancelToken: cancelToken,
          options: options,
          onSendProgress: onSendProgress,
          onReceiveProgress: onReceiveProgress);

      //LogUtils.e(response.data);
      if (bIsShowLoading) {
        MyGlobal.hideLoading();
      }

      if (bIsShowResponse) {
        final responseData = response.data;
        String prettyData;

        if (responseData is String && isValidJson(responseData)) {
          // 如果是 JSON 格式字符串，格式化输出
          prettyData = prettyJson(jsonDecode(responseData));
        } else if (responseData is Map || responseData is List) {
          // 如果是直接的 JSON 对象
          prettyData = prettyJson(responseData);
        } else {
          // 如果既不是 JSON 对象也不是 JSON 格式字符串，直接输出原始内容
          prettyData = responseData.toString();
        }

        Logger().d("********** Response **********\n"
            "time: ${DateTime.now()}\n"
            "url: ${response.requestOptions.path.contains("://") ? "" : response.requestOptions.baseUrl}${response.requestOptions.path}\n"
            "statusMessage: ${response.statusMessage}\n"
            "statusCode: ${response.statusCode}\n"
            "data:$prettyData"
            //"data: ${prettyJson((response.data is String) ? jsonDecode(response.data) : response.data)}"
            );

        // LoggerService.logData("********** Response **********\n"
        //     "time: ${DateTime.now()}\n"
        //     "url: ${response.requestOptions.path.contains("://") ? "" : response.requestOptions.baseUrl}${response.requestOptions.path}\n"
        //     "statusMessage: ${response.statusMessage}\n"
        //     "statusCode: ${response.statusCode}\n"
        //     "data: ${prettyJson((response.data is String) ? jsonDecode(response.data) : response.data)}");
      }

      return response.data;
      // ignore: deprecated_member_use
    } on DioError catch (error) {
      //LogUtils.e("网络请求出错 " + error.toString());
      print("error:$error");

      if (bIsShowLoading) {
        MyGlobal.hideLoading();
      }

      if (error.response != null &&
          error.response!.data is Map<String, dynamic>) {
        Map<String, dynamic> responseData =
            error.response!.data as Map<String, dynamic>;

        String? message = responseData["message"];

        if (message != null && message.isNotEmpty) {
          String cleanedContent =
              message.replaceAll(RegExp(r'<a[^>]*>.*?</a>'), '');
          print(cleanedContent);

          MyGlobal.showError(cleanedContent,
              timeLen: Toast.LENGTH_LONG, itime: 5);
        } else {
          int code = error.response!.statusCode!;

          if (code == 401) {
            MyGlobal.showError("没有权限", timeLen: Toast.LENGTH_LONG);
          } else {
            MyGlobal.showError(code.toString(), timeLen: Toast.LENGTH_LONG);
          }
        }

        if (callbackOnFail != null) {
          callbackOnFail();
        }
      } else {
        // 处理其他情况，例如 response 为空或数据不是 Map 类型
        // 这里可以添加其他错误处理逻辑

        if (callbackOnFail != null) {
          callbackOnFail();
        }
      }

      //rethrow;
      return response?.data;
    }
  }

  bool isValidJson(String str) {
    try {
      jsonDecode(str);
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 开启日志打印
  /// 需要打印日志的接口在接口请求前 DioUtil.instance?.openLog();
  void openLog() {
    // _dioForBaseUrl1.interceptors
    //     .add(LogInterceptor(responseHeader: false, responseBody: true));

    // _dioForBaseUrl3.interceptors
    //     .add(LogInterceptor(responseHeader: false, responseBody: true));
  }
}

// 发起GET请求示例
// void fetchData() async {
//   var response = await DioHttps().request(
//     '/api/data', // 请求的路径
//     method: PTDioMethod.get, // 请求类型：GET
//     params: {'key': 'value'}, // 请求参数
//   );

//   // 处理响应数据
//   print(response);
// }
